package com.example.chatty.ui.IMChat

import androidx.compose.foundation.Image
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material.Divider
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.LastBaseline
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.unit.dp
import com.example.chatty.R
import com.example.chatty.logic.model.AppScreen
import com.example.chatty.logic.model.Message
import com.example.chatty.screens.conversation.LocalConversationUser
import com.example.chatty.screens.conversation.SymbolAnnotationType
import com.example.chatty.screens.conversation.messageFormatter
import com.example.chatty.ui.theme.chattyColors

@Composable
fun Messages(
    messages: List<Message>,
    navigateToProfile: (String) -> Unit,
    scrollState: LazyListState,
    modifier: Modifier = Modifier
) {

    val conversationUser = LocalConversationUser.current
    Box(modifier = modifier) {
        LazyColumn(
            state = scrollState,
            contentPadding = WindowInsets.statusBars.add(WindowInsets(top = 20.dp))
                .asPaddingValues(),
            modifier = Modifier.fillMaxSize(),
            reverseLayout = true
        ) {
            for (index in messages.indices) {
                val preTime = messages.getOrNull(index - 1)?.timestamp
                val nextTime = messages.getOrNull(index + 1)?.timestamp
                val content = messages[index]
                val isFirstMessageByTime = preTime != content.timestamp
                val isLastMessageByTime = nextTime != content.timestamp
                if (index == messages.size - 1) {
                    item {
                        DayHeader("8月20日")
                    }
                } else if (index == 2) {
                    item {
                        DayHeader("今天")
                    }
                }
                item {
                    Message(
                        onAuthorClick = { navigateToProfile("${AppScreen.conversation}/${conversationUser.uid}") },
                        msg = content,
                        isUserMe = content.isUserMe,
                        isFirstMessageByAuthor = isFirstMessageByTime,
                        isLastMessageByAuthor = isLastMessageByTime
                    )
                }

            }


        }
    }


}

@Composable
fun DayHeader(dayString: String) {
    Row(
        modifier = Modifier
            .padding(vertical = 8.dp, horizontal = 16.dp)
            .wrapContentHeight()
    ) {
        DayHeaderLine()
        Text(
            text = dayString,
            modifier = Modifier.padding(horizontal = 16.dp),
            color = MaterialTheme.chattyColors.disabledContent
        )
        DayHeaderLine()
    }
}

@Composable
private fun RowScope.DayHeaderLine() {
    Divider(
        modifier = Modifier
            .weight(1f)
            .align(Alignment.CenterVertically),
        color = MaterialTheme.chattyColors.disabledContent
    )
}


@Composable
fun Message(
    onAuthorClick: () -> Unit,
    msg: Message,
    isUserMe: Boolean,
    isFirstMessageByAuthor: Boolean,
    isLastMessageByAuthor: Boolean,
) {
    val borderColor = if (isUserMe) {
        MaterialTheme.colorScheme.primary
    } else {
        MaterialTheme.colorScheme.secondary
    }

    val spaceBetweenAuthors = if (isLastMessageByAuthor) Modifier.padding(top = 8.dp) else Modifier

    Row(modifier = spaceBetweenAuthors) {
        if (isLastMessageByAuthor) {
            Image(
                painter = painterResource(id = if (isUserMe) R.drawable.ava2 else LocalConversationUser.current.avatarRes),
                contentDescription = null,
                modifier = Modifier
                    .clickable { onAuthorClick() }
                    .padding(horizontal = 16.dp)
                    .size(42.dp)
                    .border(
                        width = 1.5.dp,
                        color = borderColor,
                        shape = CircleShape
                    )
                    .clip(
                        CircleShape
                    )
                    .align(Alignment.Top),
                contentScale = ContentScale.Crop
            )
        } else {
            Spacer(modifier = Modifier.width(74.dp))
        }
        AuthorAndTextMessage(
            msg = msg,
            isUserMe = isUserMe,
            isFirstMessageByTime = isFirstMessageByAuthor,
            isLastMessageByTime = isLastMessageByAuthor,
            authorClicked = onAuthorClick,
            modifier = Modifier
                .padding(end = 16.dp)
                .weight(1f)
        )
    }
}

@Composable
fun AuthorAndTextMessage(
    msg: Message,
    isUserMe: Boolean,
    isFirstMessageByTime: Boolean,
    isLastMessageByTime: Boolean,
    authorClicked: () -> Unit,
    modifier: Modifier = Modifier
) {
    Column(modifier) {
        if (isLastMessageByTime) {
            AuthorNameTimestamp(msg)
        }
        ChatItemBubble(msg, isUserMe)
        if (isFirstMessageByTime) {
            Spacer(modifier = Modifier.height(8.dp))
        } else {
            Spacer(modifier = Modifier.height(4.dp))
        }
    }
}

@Composable
private fun AuthorNameTimestamp(msg: Message) {
    Row(modifier = Modifier.semantics(true) {}) {
        Text(
            text = if (msg.isUserMe) stringResource(id = R.string.author_me)
            else LocalConversationUser.current.nickname,
            style = MaterialTheme.typography.titleMedium,
            modifier = Modifier
                .alignBy(LastBaseline)
                .paddingFrom(LastBaseline, after = 8.dp)
        )
        Spacer(modifier = Modifier.width(8.dp))
        Text(
            text = msg.timestamp,
            style = MaterialTheme.typography.titleSmall.copy(MaterialTheme.chattyColors.conversationHintText),
            modifier = Modifier.alignBy(LastBaseline)
        )
    }
}

private val ChatBubbleShape = RoundedCornerShape(4.dp, 20.dp, 20.dp, 20.dp)
private val backgroundBubbleColor = Color(0x1244DDD8)
private val ConversationBubbleElevation = 1.dp

@Composable
fun ChatItemBubble(message: Message, isUserMe: Boolean) {
    val backgroundBubbleColor = if (isUserMe) {
        MaterialTheme.chattyColors.conversationBubbleBgMe
    } else {
        MaterialTheme.chattyColors.conversationBubbleBg
    }
    Column() {
        Surface(
            shape = ChatBubbleShape,
            color = backgroundBubbleColor,
            elevation = ConversationBubbleElevation,
        ) {
            ClickableMessage(message, isUserMe)
        }
        message.image?.also {
            Spacer(modifier = Modifier.height(4.dp))
            Surface(
                shape = ChatBubbleShape,
                color = backgroundBubbleColor,
                elevation = ConversationBubbleElevation,
            ) {
                Image(
                    painterResource(id = it),
                    contentDescription = stringResource(id = R.string.attached_image),
                    contentScale = ContentScale.Fit,
                    modifier = Modifier.size(160.dp)
                )
            }
        }
    }
}


@Composable
fun ClickableMessage(msg: Message, isUserMe: Boolean) {
    val uriHandler = LocalUriHandler.current
    val styledMessage: AnnotatedString = messageFormatter(text = msg.content, primary = isUserMe)

    ClickableText(
        text = styledMessage,
        style = MaterialTheme.typography.bodyMedium.copy(
            color = if (isUserMe) MaterialTheme.chattyColors.conversationTextMe
            else MaterialTheme.chattyColors.conversationText
        ),
        modifier = Modifier.padding(16.dp),
        onClick = {
            styledMessage.getStringAnnotations(start = it, end = it).firstOrNull()
                ?.let { annotation ->
                    when (annotation.tag) {
                        SymbolAnnotationType.LINK.name -> uriHandler.openUri(annotation.item)
                        else -> Unit
                    }
                }
        }
    )
}




